/**
 * @file dumper.h
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2020-10-29
 *
 * @copyright Copyright (c) 2020
 *
 */
#pragma once
#include <fstream>
#include <functional>
#include <memory>
#include <string>
#include <vector>
using namespace std;

class Dumper {
public:
  // Dumper is not copyable.
  Dumper(const Dumper &) = delete;
  Dumper &operator=(const Dumper &) = delete;

  function<void(string, string, string, size_t *, size_t, double)> DumpHeader;
  function<void(string, float *var, size_t num)> DumpVariables;
  function<void()> DumpTail;
  static void DumpTecplotHeaderBinary(string file_name, string var_name,
                                      string zone_name, size_t *sizes,
                                      size_t num_node_variables,
                                      double solution_time);
  static void DumpTecplotHeaderASCII(string file_name, string var_name,
                                     string zone_name, size_t *sizes,
                                     size_t num_node_variables,
                                     double solution_time);
  static void DumpTecplotVariablesBinary(string file_name, float *var,
                                         size_t num);
  static void DumpTecplotVariablesASCII(string file_name, float *var,
                                        size_t num);
  static void DumpTecplotTailBinary();
  static void DumpTecplotTailASCII(){};

  static Dumper &Instance(bool is_output_binary) {
    static Dumper Instance(is_output_binary);
    return Instance;
  }

private:
  const bool kIsOutputBinary;
  Dumper(bool is_output_binary) : kIsOutputBinary(is_output_binary) {
    if (kIsOutputBinary) {
      DumpHeader = DumpTecplotHeaderBinary;
      DumpVariables = DumpTecplotVariablesBinary;
      DumpTail = DumpTecplotTailBinary;
    } else {
      DumpHeader = DumpTecplotHeaderASCII;
      DumpVariables = DumpTecplotVariablesASCII;
      DumpTail = DumpTecplotTailASCII;
    }
  }
  ~Dumper() = default;
};
